package com.young.common.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class JJwtUtils {

    private static final Map<String, Object> DEFAULT_HEADER;
    private static final             String  DEFAULT_SECRET;
    private static final                int  DEFAULT_EXPIRE_TIME_HOURS;

    static {
        DEFAULT_SECRET = "YOUNG121211112221111222111111111"; // 长度为32
        DEFAULT_HEADER = new HashMap<String, Object>(){{
            put("org", "YOUNG");
            put("alg", "HMAC256");
            put("typ", "JJWT");
        }};
        DEFAULT_EXPIRE_TIME_HOURS = 12;
    }

    public static String generateJWTToken(String subject, Map<String, Object> claims, Integer expireHours) {
        expireHours = null == expireHours ? DEFAULT_EXPIRE_TIME_HOURS : expireHours;
        Date now = new Date();
        return Jwts.builder()
            .setHeaderParams(DEFAULT_HEADER)
            .addClaims(claims)
            .setSubject(subject)
            .setIssuedAt(now)
            .signWith(generateKey(), SignatureAlgorithm.HS256)
            .setExpiration(new Date(now.getTime() + expireHours * 60 * 60 * 1000))
            .compact();
    }

    public static Claims parseToken(String token) throws Exception {
        JwtParser parserBuilder = Jwts.parserBuilder().setSigningKey(generateKey()).build();
        return parserBuilder.parseClaimsJws(token).getBody();
    }

    private static SecretKey generateKey() {
        byte[] encodeKey = Base64.getEncoder().encode(DEFAULT_SECRET.getBytes(StandardCharsets.UTF_8));
        return new SecretKeySpec(encodeKey, 0, DEFAULT_SECRET.length(), "HmacSHA256");
    }

    public static void main(String[] args) {
        Map<String, Object> params = new HashMap<String, Object>(){{
           put("a", "1");
           put("hello", "world");
           put("name", "zgx");
        }};
        String token = generateJWTToken("10012", params, 1);
        System.out.println(token);
        try {
            Claims claims = parseToken(token);
            System.out.println(claims.getSubject());
            System.out.println(claims.get("a"));
            System.out.println(claims.get("hello"));
            System.out.println(claims.get("name"));
        } catch (Exception e) {
            log.info("---", e);
        }
    }

}
